package com.example.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.web.SysConst;
import com.example.web.dto.*;
import com.example.web.dto.query.*;
import com.example.web.entity.*;
import com.example.web.mapper.*;
import com.example.web.service.*;
import com.example.web.tools.dto.*;
import com.example.web.tools.exception.CustomException;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import lombok.SneakyThrows;
import com.example.web.tools.*;
/**
 * 订单功能实现类
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

	 /**
     * 操作数据库AppUser表mapper对象
     */
    @Autowired
    private AppUserMapper _AppUserMapper;
    /**
     * 操作数据库的OrderInfo表mapper对象
     */
    @Autowired
    private OrderInfoMapper _OrderInfoMpper;

 			
  	 @Autowired
    private OrderDetailMapper _OrderDetailMapper;

    /**
     * 操作数据库的Good表mapper对象
     */
    @Autowired
    private GoodMapper _GoodMpper;



    /**
     * 订单分页查询
     */
    @SneakyThrows
    @Override
    public PagedResult<OrderInfoDto> List(OrderInfoPagedInput input) {

      
        //声明一个支持订单查询的(拉姆达)表达式
        LambdaQueryWrapper<OrderInfo> queryWrapper = Wrappers.<OrderInfo>lambdaQuery()
                .eq(input.getId()!=null&&input.getId()!=0,OrderInfo::getId,input.getId())
                .eq(input.getCreatorId()!=null,OrderInfo::getCreatorId,input.getCreatorId());
      
     	 //如果前端搜索传入Code不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getCode())) {
            queryWrapper=queryWrapper.eq(OrderInfo::getCode,input.getCode());
       	 }
     	 //如果前端搜索传入LinkName不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getLinkName())) {
            queryWrapper=queryWrapper.eq(OrderInfo::getLinkName,input.getLinkName());
       	 }
     	 //如果前端搜索传入Phone不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getPhone())) {
            queryWrapper=queryWrapper.eq(OrderInfo::getPhone,input.getPhone());
       	 }
     	 //如果前端搜索传入Address不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getAddress())) {
            queryWrapper=queryWrapper.eq(OrderInfo::getAddress,input.getAddress());
       	 }
     	 //如果前端搜索传入BuyUserId不为空,则进行精确查询
        if(input.getBuyUserId()!=null) {
            queryWrapper=queryWrapper.eq(OrderInfo::getBuyUserId,input.getBuyUserId());
       	 }
     	 //如果前端搜索传入Remark不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getRemark())) {
            queryWrapper=queryWrapper.eq(OrderInfo::getRemark,input.getRemark());
       	 }
     	 //如果前端搜索传入LogisticsNo不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getLogisticsNo())) {
            queryWrapper=queryWrapper.eq(OrderInfo::getLogisticsNo,input.getLogisticsNo());
       	 }
     	 //如果前端搜索传入OrderStatus不为空,则进行精确查询
        if(input.getOrderStatus()!=null) {
            queryWrapper=queryWrapper.eq(OrderInfo::getOrderStatus,input.getOrderStatus());
       	 }
     	 //如果前端搜索传入PayType不为空,则进行精确查询
        if(Extension.isNotNullOrEmpty(input.getPayType())) {
            queryWrapper=queryWrapper.eq(OrderInfo::getPayType,input.getPayType());
       	 }
      
        //按创建时间从大到小排序 最新的显示在最前面
        queryWrapper=queryWrapper.orderByDesc(OrderInfo::getCreationTime);
        //构建一个分页查询的model
        Page<OrderInfo> page = new Page<>(input.getPage(), input.getLimit());
          
   
         //从数据库进行分页查询获取订单数据
        IPage<OrderInfo> pageRecords= _OrderInfoMpper.selectPage(page, queryWrapper);

        //获取所有满足条件的数据行数
        Long totalCount= _OrderInfoMpper.selectCount(queryWrapper);

        //把OrderInfo实体转换成OrderInfo传输模型
        List<OrderInfoDto> items= Extension.copyBeanList(pageRecords.getRecords(),OrderInfoDto.class);
        for (OrderInfoDto item : items) {
          
          //查询出关联的创建用户信息
            AppUserDto  CreatorAppUserDTO=new AppUserDto();
            AppUser  CreatorAppUserEntity= _AppUserMapper.selectOne(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getId,item.getCreatorId()));
           if(CreatorAppUserEntity!=null) {
                BeanUtils.copyProperties(CreatorAppUserDTO, CreatorAppUserEntity);
                item.setCreatorAppUserDto(CreatorAppUserDTO);
            }  
         

            //查询关联的OrderDetail表信息
            List<OrderDetail>  OrderDetailEntitys= _OrderDetailMapper.selectList(Wrappers.<OrderDetail>lambdaQuery().eq(OrderDetail::getOrderInfoId,item.getId()));
            List<OrderDetailDto> OrderDetailDTOS= Extension.copyBeanList(OrderDetailEntitys,OrderDetailDto.class);
            item.setOrderDetailDtos(OrderDetailDTOS);
         
           
          	            
           //查询出关联的AppUser表信息
           AppUserDto BuyUserDTO = new AppUserDto();        
            AppUser  BuyUserEntity= _AppUserMapper.selectOne(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getId,item.getBuyUserId()));
           if(BuyUserEntity!=null) {  
          BeanUtils.copyProperties(BuyUserDTO,BuyUserEntity);
            item.setBuyUserDto(BuyUserDTO); 
           }
          
        }
      
        //返回一个分页结构给前端
        return PagedResult.GetInstance(items,totalCount);

    }
  
    /**
     * 单个订单查询
     */
    @SneakyThrows
    @Override
    public OrderInfoDto Get(OrderInfoPagedInput input) {
       if(input.getId()==null)
        {
            return new OrderInfoDto();
        }
        PagedResult<OrderInfoDto>  pagedResult =List(input);
        return pagedResult.getTotalCount()>0?pagedResult.getItems().stream().findFirst().get():new OrderInfoDto();
    }

    /**
     *订单创建或者修改
     */
    @SneakyThrows
    @Override
    public OrderInfoDto CreateOrEdit(OrderInfoDto input) {


        //创建订单走这个逻辑
        if("ToOrder".equals(input.getBehavior()))
        {

            //查询订单明细的商品库存是否够
            for (OrderDetailDto orderDetailDto :  input.getOrderDetailDtos()) {

                //查询商品
                Good good = _GoodMpper.selectById(orderDetailDto.getGoodId());
                if(orderDetailDto.getNumber()<=0)
                {
                    throw new CustomException(good.getName()+"购买的数量不能小于等于0");
                }
                if(good.getStock()<orderDetailDto.getNumber())
                 {
                     throw new CustomException(good.getName()+"库存数量不足");
                 }

                good.setStock(good.getStock()-orderDetailDto.getNumber());
                _GoodMpper.updateById(good);
            }
            //声明一个订单实体
            OrderInfo OrderInfo = new OrderInfo();
            //把前端传入的input参数拷贝到订单实体
            BeanUtils.copyProperties(OrderInfo, input);

            OrderInfo.setCode("D"+Extension.GenerateOrderNumber());
            //调用数据库的增加或者修改方法
            saveOrUpdate(OrderInfo);

            List<OrderDetail> orderDetails = Extension.copyBeanList(input.getOrderDetailDtos(), OrderDetail.class);
            for (OrderDetail orderDetail : orderDetails) {
                orderDetail.setOrderInfoId(OrderInfo.getId());
                _OrderDetailMapper.insert(orderDetail);
            }
            //调用数据库的增加或者修改方法
            saveOrUpdate(OrderInfo);

            //定义一个返回给前端的订单传输模型
            OrderInfoDto OrderInfoDto = new OrderInfoDto();

            //同理把操作的订单实体拷贝给订单传输模型
            BeanUtils.copyProperties(OrderInfoDto, OrderInfo);

            //把传输模型返回给前端
            return OrderInfoDto;
        }
        else {
            //如果是修改订单主表 走这条逻辑
            //声明一个订单实体
            OrderInfo OrderInfo = new OrderInfo();

            //把前端传入的input参数拷贝到订单实体
            BeanUtils.copyProperties(OrderInfo, input);

            //调用数据库的增加或者修改方法
            saveOrUpdate(OrderInfo);

            //定义一个返回给前端的订单传输模型
            OrderInfoDto OrderInfoDto = new OrderInfoDto();

            //同理把操作的订单实体拷贝给订单传输模型
            BeanUtils.copyProperties(OrderInfoDto, OrderInfo);

            //把传输模型返回给前端
            return OrderInfoDto;
        }
    }



}
